#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->processButton->setEnabled(false);
    ui->label->setText(QString::number(ui->neighbourSlider->value()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_openButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
           tr("Open Image"), ".", tr("Image Files (*.png *.jpg *.bmp)"));
       m_originalImg = cv::imread(fileName.toUtf8().data());
       if(m_originalImg.data) {
           this->displayOriginalImage();
           ui->processButton->setEnabled(true);
           ui->withIterative_rb->setEnabled(true);
           ui->withOpenCV_rb->setEnabled(true);
           ui->withAdaptive_rb->setEnabled(true);
           ui->withIterative_rb->setChecked(true);
       }
}

void MainWindow::on_neighbourSlider_valueChanged(int newval){
    ui->label->setText(QString::number(newval));
}

void MainWindow::on_thresholdSlider_valueChanged(int newval){
    ui->sliderValueLabel->setText(QString::number(newval));
}

void MainWindow::on_processButton_clicked()
{
    double duration;
    duration = static_cast<double> (cv::getTickCount());

    // process image
    if(ui->withIterative_rb->isChecked()){
        processImage();
    }
    else {
        if(ui->withOpenCV_rb->isChecked()){
            processImageOpenCV_threshold();
        }
        else {
            if(ui->withAdaptive_rb->isChecked()){
                processImageOpenCV_adaptive();
            }
        }
    }

    duration = static_cast<double>(cv::getTickCount())-duration;
    // die verstrichene Zeit in ms
    duration /= cv::getTickFrequency();
    ui->durationValueLabel->setText(QString::number(duration*1000.0, 'f', 2) + "us");
}

void MainWindow::processImage()
{
    // Aendere Farbkanalanordnung in 1 channel 8bit
    cv::Mat processImg;
    cv::cvtColor(m_originalImg, processImg, CV_BGR2GRAY);

    if(processImg.channels() == 1){
        if(processImg.type() == CV_8U){
           // singlechannel
            int nl = processImg.rows;
            int nc = processImg.cols * processImg.channels();

            for (int j=0; j<nl; j++) {
                for (int i=0; i< nc; i++) {
                    if(processImg.at<uchar>(j,i) < ui->thresholdSlider->value()){
                        // black
                        processImg.at<uchar>(j,i)=0;
                    }
                    else {
                        // white
                        processImg.at<uchar>(j,i)=255;
                    }
                }
            }
            displayImage(processImg);
        }
    }
    else {
        ui->processImgLabel->setText("Konvertierungsfehler");
    }
}

void MainWindow::processImageOpenCV_threshold()
{
    // get threshold
    double threshold = ui->thresholdSlider->value();

    // Aendere Farbkanalanordnung in 1 channel 8bit
    cv::Mat processImg;
    cv::cvtColor(m_originalImg, processImg, CV_BGR2GRAY);

    cv::threshold(processImg, processImg, threshold,255,cv::THRESH_BINARY);
    displayImage(processImg);
}

void MainWindow::processImageOpenCV_adaptive()
{
    // Aendere Farbkanalanordnung in 1 channel 8bit
    cv::Mat processImg;
    cv::cvtColor(m_originalImg, processImg, CV_BGR2GRAY);

    int val = ui->neighbourSlider->value();
    if((val % 2) == 0) val += 1;

    cv::adaptiveThreshold(processImg,processImg,
                          255,
                          cv::ADAPTIVE_THRESH_MEAN_C,
                          cv::THRESH_BINARY,
                          val,
                          1);
    displayImage(processImg);
}

void MainWindow::displayImage(cv::Mat image)
{
    // Erzeuge ein Qt image
    QImage img = QImage((uchar*) image.data, image.cols, image.rows, image.step, QImage::Format_Indexed8);

    if(ui->processImgLabel) {
        // Erzeuge eine Pixmap
        QPixmap pixmap = QPixmap::fromImage(img);

        // Zeige Pixmap im Label an
        ui->processImgLabel->setPixmap(pixmap);

        // Groessenanpassung des Labels fuer das Bild durchfuehren
        ui->processImgLabel->resize(ui->processImgLabel->pixmap()->size());
    }
}

void MainWindow::displayOriginalImage()
{
    // Aendere Farbkanalanordnung fuer Qt
    cv::Mat image = m_originalImg;
    cv::cvtColor(image, image, CV_BGR2RGB);

    // Erzeuge ein Qt image
    QImage img = QImage((uchar*) image.data, image.cols, image.rows, image.step, QImage::Format_RGB888).scaledToWidth(ui->baseImgLabel->width());

    if(ui->baseImgLabel) {
        // Erzeuge eine Pixmap
        QPixmap pixmap = QPixmap::fromImage(img);

        // Zeige Pixmap im Label an
        ui->baseImgLabel->setPixmap(pixmap);
    }
}
